home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / cd_win.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-13  |  10.6 KB  |  511 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
  21. // rights reserved.
  22.  
  23. #include <windows.h>
  24. #include "../client/client.h"
  25.  
  26. extern    HWND    cl_hwnd;
  27.  
  28. static qboolean cdValid = false;
  29. static qboolean    playing = false;
  30. static qboolean    wasPlaying = false;
  31. static qboolean    initialized = false;
  32. static qboolean    enabled = false;
  33. static qboolean playLooping = false;
  34. static byte     remap[100];
  35. static byte        cdrom;
  36. static byte        playTrack;
  37. static byte        maxTrack;
  38.  
  39. cvar_t *cd_nocd;
  40. cvar_t *cd_loopcount;
  41. cvar_t *cd_looptrack;
  42.  
  43. UINT    wDeviceID;
  44. int        loopcounter;
  45.  
  46.  
  47. void CDAudio_Pause(void);
  48.  
  49. static void CDAudio_Eject(void)
  50. {
  51.     DWORD    dwReturn;
  52.  
  53.     if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, (DWORD)NULL))
  54.         Com_DPrintf("MCI_SET_DOOR_OPEN failed (%i)\n", dwReturn);
  55. }
  56.  
  57.  
  58. static void CDAudio_CloseDoor(void)
  59. {
  60.     DWORD    dwReturn;
  61.  
  62.     if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, (DWORD)NULL))
  63.         Com_DPrintf("MCI_SET_DOOR_CLOSED failed (%i)\n", dwReturn);
  64. }
  65.  
  66.  
  67. static int CDAudio_GetAudioDiskInfo(void)
  68. {
  69.     DWORD                dwReturn;
  70.     MCI_STATUS_PARMS    mciStatusParms;
  71.  
  72.  
  73.     cdValid = false;
  74.  
  75.     mciStatusParms.dwItem = MCI_STATUS_READY;
  76.     dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
  77.     if (dwReturn)
  78.     {
  79.         Com_DPrintf("CDAudio: drive ready test - get status failed\n");
  80.         return -1;
  81.     }
  82.     if (!mciStatusParms.dwReturn)
  83.     {
  84.         Com_DPrintf("CDAudio: drive not ready\n");
  85.         return -1;
  86.     }
  87.  
  88.     mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
  89.     dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
  90.     if (dwReturn)
  91.     {
  92.         Com_DPrintf("CDAudio: get tracks - status failed\n");
  93.         return -1;
  94.     }
  95.     if (mciStatusParms.dwReturn < 1)
  96.     {
  97.         Com_DPrintf("CDAudio: no music tracks\n");
  98.         return -1;
  99.     }
  100.  
  101.     cdValid = true;
  102.     maxTrack = mciStatusParms.dwReturn;
  103.  
  104.     return 0;
  105. }
  106.  
  107.  
  108.  
  109. void CDAudio_Play2(int track, qboolean looping)
  110. {
  111.     DWORD                dwReturn;
  112.     MCI_PLAY_PARMS        mciPlayParms;
  113.     MCI_STATUS_PARMS    mciStatusParms;
  114.  
  115.     if (!enabled)
  116.         return;
  117.     
  118.     if (!cdValid)
  119.     {
  120.         CDAudio_GetAudioDiskInfo();
  121.         if (!cdValid)
  122.             return;
  123.     }
  124.  
  125.     track = remap[track];
  126.  
  127.     if (track < 1 || track > maxTrack)
  128.     {
  129.         CDAudio_Stop();
  130.         return;
  131.     }
  132.  
  133.     // don't try to play a non-audio track
  134.     mciStatusParms.dwItem = MCI_CDA_STATUS_TYPE_TRACK;
  135.     mciStatusParms.dwTrack = track;
  136.     dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
  137.     if (dwReturn)
  138.     {
  139.         Com_DPrintf("MCI_STATUS failed (%i)\n", dwReturn);
  140.         return;
  141.     }
  142.     if (mciStatusParms.dwReturn != MCI_CDA_TRACK_AUDIO)
  143.     {
  144.         Com_Printf("CDAudio: track %i is not audio\n", track);
  145.         return;
  146.     }
  147.  
  148.     // get the length of the track to be played
  149.     mciStatusParms.dwItem = MCI_STATUS_LENGTH;
  150.     mciStatusParms.dwTrack = track;
  151.     dwReturn = mciSendCommand(wDeviceID, MCI_STATUS, MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD) (LPVOID) &mciStatusParms);
  152.     if (dwReturn)
  153.     {
  154.         Com_DPrintf("MCI_STATUS failed (%i)\n", dwReturn);
  155.         return;
  156.     }
  157.  
  158.     if (playing)
  159.     {
  160.         if (playTrack == track)
  161.             return;
  162.         CDAudio_Stop();
  163.     }
  164.  
  165.     mciPlayParms.dwFrom = MCI_MAKE_TMSF(track, 0, 0, 0);
  166.     mciPlayParms.dwTo = (mciStatusParms.dwReturn << 8) | track;
  167.     mciPlayParms.dwCallback = (DWORD)cl_hwnd;
  168.     dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD)(LPVOID) &mciPlayParms);
  169.     if (dwReturn)
  170.     {
  171.         Com_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn);
  172.         return;
  173.     }
  174.  
  175.     playLooping = looping;
  176.     playTrack = track;
  177.     playing = true;
  178.  
  179.     if ( Cvar_VariableValue( "cd_nocd" ) )
  180.         CDAudio_Pause ();
  181. }
  182.  
  183.  
  184. void CDAudio_Play(int track, qboolean looping)
  185. {
  186.     // set a loop counter so that this track will change to the
  187.     // looptrack later
  188.     loopcounter = 0;
  189.     CDAudio_Play2(track, looping);
  190. }
  191.  
  192. void CDAudio_Stop(void)
  193. {
  194.     DWORD    dwReturn;
  195.  
  196.     if (!enabled)
  197.         return;
  198.     
  199.     if (!playing)
  200.         return;
  201.  
  202.     if (dwReturn = mciSendCommand(wDeviceID, MCI_STOP, 0, (DWORD)NULL))
  203.         Com_DPrintf("MCI_STOP failed (%i)", dwReturn);
  204.  
  205.     wasPlaying = false;
  206.     playing = false;
  207. }
  208.  
  209.  
  210. void CDAudio_Pause(void)
  211. {
  212.     DWORD                dwReturn;
  213.     MCI_GENERIC_PARMS    mciGenericParms;
  214.  
  215.     if (!enabled)
  216.         return;
  217.  
  218.     if (!playing)
  219.         return;
  220.  
  221.     mciGenericParms.dwCallback = (DWORD)cl_hwnd;
  222.     if (dwReturn = mciSendCommand(wDeviceID, MCI_PAUSE, 0, (DWORD)(LPVOID) &mciGenericParms))
  223.         Com_DPrintf("MCI_PAUSE failed (%i)", dwReturn);
  224.  
  225.     wasPlaying = playing;
  226.     playing = false;
  227. }
  228.  
  229.  
  230. void CDAudio_Resume(void)
  231. {
  232.     DWORD            dwReturn;
  233.     MCI_PLAY_PARMS    mciPlayParms;
  234.  
  235.     if (!enabled)
  236.         return;
  237.     
  238.     if (!cdValid)
  239.         return;
  240.  
  241.     if (!wasPlaying)
  242.         return;
  243.     
  244.     mciPlayParms.dwFrom = MCI_MAKE_TMSF(playTrack, 0, 0, 0);
  245.     mciPlayParms.dwTo = MCI_MAKE_TMSF(playTrack + 1, 0, 0, 0);
  246.     mciPlayParms.dwCallback = (DWORD)cl_hwnd;
  247.     dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_TO | MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms);
  248.     if (dwReturn)
  249.     {
  250.         Com_DPrintf("CDAudio: MCI_PLAY failed (%i)\n", dwReturn);
  251.         return;
  252.     }
  253.     playing = true;
  254. }
  255.  
  256.  
  257. static void CD_f (void)
  258. {
  259.     char    *command;
  260.     int        ret;
  261.     int        n;
  262.  
  263.     if (Cmd_Argc() < 2)
  264.         return;
  265.  
  266.     command = Cmd_Argv (1);
  267.  
  268.     if (Q_strcasecmp(command, "on") == 0)
  269.     {
  270.         enabled = true;
  271.         return;
  272.     }
  273.  
  274.     if (Q_strcasecmp(command, "off") == 0)
  275.     {
  276.         if (playing)
  277.             CDAudio_Stop();
  278.         enabled = false;
  279.         return;
  280.     }
  281.  
  282.     if (Q_strcasecmp(command, "reset") == 0)
  283.     {
  284.         enabled = true;
  285.         if (playing)
  286.             CDAudio_Stop();
  287.         for (n = 0; n < 100; n++)
  288.             remap[n] = n;
  289.         CDAudio_GetAudioDiskInfo();
  290.         return;
  291.     }
  292.  
  293.     if (Q_strcasecmp(command, "remap") == 0)
  294.     {
  295.         ret = Cmd_Argc() - 2;
  296.         if (ret <= 0)
  297.         {
  298.             for (n = 1; n < 100; n++)
  299.                 if (remap[n] != n)
  300.                     Com_Printf("  %u -> %u\n", n, remap[n]);
  301.             return;
  302.         }
  303.         for (n = 1; n <= ret; n++)
  304.             remap[n] = atoi(Cmd_Argv (n+1));
  305.         return;
  306.     }
  307.  
  308.     if (Q_strcasecmp(command, "close") == 0)
  309.     {
  310.         CDAudio_CloseDoor();
  311.         return;
  312.     }
  313.  
  314.     if (!cdValid)
  315.     {
  316.         CDAudio_GetAudioDiskInfo();
  317.         if (!cdValid)
  318.         {
  319.             Com_Printf("No CD in player.\n");
  320.             return;
  321.         }
  322.     }
  323.  
  324.     if (Q_strcasecmp(command, "play") == 0)
  325.     {
  326.         CDAudio_Play(atoi(Cmd_Argv (2)), false);
  327.         return;
  328.     }
  329.  
  330.     if (Q_strcasecmp(command, "loop") == 0)
  331.     {
  332.         CDAudio_Play(atoi(Cmd_Argv (2)), true);
  333.         return;
  334.     }
  335.  
  336.     if (Q_strcasecmp(command, "stop") == 0)
  337.     {
  338.         CDAudio_Stop();
  339.         return;
  340.     }
  341.  
  342.     if (Q_strcasecmp(command, "pause") == 0)
  343.     {
  344.         CDAudio_Pause();
  345.         return;
  346.     }
  347.  
  348.     if (Q_strcasecmp(command, "resume") == 0)
  349.     {
  350.         CDAudio_Resume();
  351.         return;
  352.     }
  353.  
  354.     if (Q_strcasecmp(command, "eject") == 0)
  355.     {
  356.         if (playing)
  357.             CDAudio_Stop();
  358.         CDAudio_Eject();
  359.         cdValid = false;
  360.         return;
  361.     }
  362.  
  363.     if (Q_strcasecmp(command, "info") == 0)
  364.     {
  365.         Com_Printf("%u tracks\n", maxTrack);
  366.         if (playing)
  367.             Com_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
  368.         else if (wasPlaying)
  369.             Com_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
  370.         return;
  371.     }
  372. }
  373.  
  374.  
  375. LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  376. {
  377.     if (lParam != wDeviceID)
  378.         return 1;
  379.  
  380.     switch (wParam)
  381.     {
  382.         case MCI_NOTIFY_SUCCESSFUL:
  383.             if (playing)
  384.             {
  385.                 playing = false;
  386.                 if (playLooping)
  387.                 {
  388.                     // if the track has played the given number of times,
  389.                     // go to the ambient track
  390.                     if (++loopcounter >= cd_loopcount->value)
  391.                         CDAudio_Play2(cd_looptrack->value, true);
  392.                     else
  393.                         CDAudio_Play2(playTrack, true);
  394.                 }
  395.             }
  396.             break;
  397.  
  398.         case MCI_NOTIFY_ABORTED:
  399.         case MCI_NOTIFY_SUPERSEDED:
  400.             break;
  401.  
  402.         case MCI_NOTIFY_FAILURE:
  403.             Com_DPrintf("MCI_NOTIFY_FAILURE\n");
  404.             CDAudio_Stop ();
  405.             cdValid = false;
  406.             break;
  407.  
  408.         default:
  409.             Com_DPrintf("Unexpected MM_MCINOTIFY type (%i)\n", wParam);
  410.             return 1;
  411.     }
  412.  
  413.     return 0;
  414. }
  415.  
  416.  
  417. void CDAudio_Update(void)
  418. {
  419.     if ( cd_nocd->value != !enabled )
  420.     {
  421.         if ( cd_nocd->value )
  422.         {
  423.             CDAudio_Stop();
  424.             enabled = false;
  425.         }
  426.         else
  427.         {
  428.             enabled = true;
  429.             CDAudio_Resume ();
  430.         }
  431.     }
  432. }
  433.  
  434.  
  435. int CDAudio_Init(void)
  436. {
  437.     DWORD    dwReturn;
  438.     MCI_OPEN_PARMS    mciOpenParms;
  439.     MCI_SET_PARMS    mciSetParms;
  440.     int                n;
  441.  
  442.     cd_nocd = Cvar_Get ("cd_nocd", "0", CVAR_ARCHIVE );
  443.     cd_loopcount = Cvar_Get ("cd_loopcount", "4", 0);
  444.     cd_looptrack = Cvar_Get ("cd_looptrack", "11", 0);
  445.     if ( cd_nocd->value)
  446.         return -1;
  447.  
  448.     mciOpenParms.lpstrDeviceType = "cdaudio";
  449.     if (dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE, (DWORD) (LPVOID) &mciOpenParms))
  450.     {
  451.         Com_Printf("CDAudio_Init: MCI_OPEN failed (%i)\n", dwReturn);
  452.         return -1;
  453.     }
  454.     wDeviceID = mciOpenParms.wDeviceID;
  455.  
  456.     // Set the time format to track/minute/second/frame (TMSF).
  457.     mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF;
  458.     if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &mciSetParms))
  459.     {
  460.         Com_Printf("MCI_SET_TIME_FORMAT failed (%i)\n", dwReturn);
  461.         mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD)NULL);
  462.         return -1;
  463.     }
  464.  
  465.     for (n = 0; n < 100; n++)
  466.         remap[n] = n;
  467.     initialized = true;
  468.     enabled = true;
  469.  
  470.     if (CDAudio_GetAudioDiskInfo())
  471.     {
  472. //        Com_Printf("CDAudio_Init: No CD in player.\n");
  473.         cdValid = false;
  474.         enabled = false;
  475.     }
  476.  
  477.     Cmd_AddCommand ("cd", CD_f);
  478.  
  479.     Com_Printf("CD Audio Initialized\n");
  480.  
  481.     return 0;
  482. }
  483.  
  484.  
  485. void CDAudio_Shutdown(void)
  486. {
  487.     if (!initialized)
  488.         return;
  489.     CDAudio_Stop();
  490.     if (mciSendCommand(wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)NULL))
  491.         Com_DPrintf("CDAudio_Shutdown: MCI_CLOSE failed\n");
  492. }
  493.  
  494.  
  495. /*
  496. ===========
  497. CDAudio_Activate
  498.  
  499. Called when the main window gains or loses focus.
  500. The window have been destroyed and recreated
  501. between a deactivate and an activate.
  502. ===========
  503. */
  504. void CDAudio_Activate (qboolean active)
  505. {
  506.     if (active)
  507.         CDAudio_Resume ();
  508.     else
  509.         CDAudio_Pause ();
  510. }
  511.